package com.kuangqi.paymentdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.kuangqi.paymentdemo.entity.OrderInfo;
import com.kuangqi.paymentdemo.entity.PayAsyncVo;
import com.kuangqi.paymentdemo.entity.PayVo;
import com.kuangqi.paymentdemo.entity.Product;
import com.kuangqi.paymentdemo.enums.OrderStatus;
import com.kuangqi.paymentdemo.enums.alipay.TradeStatusEnums;
import com.kuangqi.paymentdemo.mapper.OrderInfoMapper;
import com.kuangqi.paymentdemo.mapper.ProductMapper;
import com.kuangqi.paymentdemo.service.OrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kuangqi.paymentdemo.util.OrderNoUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.Instant;
import java.util.List;

@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
    @Autowired
    ProductMapper productMapper;

    @Override
    public OrderInfo createInfo(Long productId) {
        OrderInfo orderInfo;
        orderInfo = this.getNopayOrderByProductId(productId);
        if (orderInfo == null) {
            Product product = productMapper.selectById(productId);
            orderInfo.setTitle(product.getTitle());
            orderInfo.setOrderNo(OrderNoUtils.getOrderNo());
            orderInfo.setProductId(productId);
            orderInfo.setTotalFee(product.getPrice() * 1000);
            orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType());
            baseMapper.insert(orderInfo);
        }
        return orderInfo;
    }

    /**
     * 收到支付成功的回调,更改数据库状态为成功
     *
     * @param orderNo
     * @param success
     */
    @Override
    public void updateStatusByOrderNo(String orderNo, OrderStatus success) {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<OrderInfo>().eq("order_no", orderNo);
        OrderInfo orderInfo = new OrderInfo();

        orderInfo.setOrderStatus(success.getType());

        baseMapper.update(orderInfo, queryWrapper);


    }

    @Override
    public String getOrderStatus(String orderNo) {
        return null;
    }


    private OrderInfo getNopayOrderByProductId(Long productId) {
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", productId);
        queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
        return baseMapper.selectOne(queryWrapper);

    }

    /**
     * 查询支付时间超过五分钟且未支付的订单
     *
     * @param minutes
     * @return
     */
    @Override
    public List<OrderInfo> getNoPayOrderInfo(Integer minutes) {

        Instant minus = Instant.now().minus(Duration.ofMinutes(minutes));
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
        queryWrapper.le("create_time", minus);

        return baseMapper.selectList(queryWrapper);


    }

    @Override
    public OrderInfo getOrderByOrderNo(String orderNo) {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);

        return orderInfo;
    }

    @Override
    public void updateStatus(PayAsyncVo payAsyncVo) {
        UpdateWrapper<OrderInfo> updateWrapper = null;
        if (TradeStatusEnums.TRADE_SUCCESS.getCode().equals(payAsyncVo.getTrade_status())) {
            updateWrapper = new UpdateWrapper<OrderInfo>().eq("order_no", payAsyncVo.getOut_trade_no()).eq("order_status", OrderStatus.NOTPAY.getType()).set("out_trade_no", payAsyncVo.getTrade_no())
                    .set("buyer_id", payAsyncVo.getBuyer_id()).set("invoice_amount", payAsyncVo.getInvoice_amount()).set("receipt_amount", payAsyncVo.getReceipt_amount()).set("order_status", OrderStatus.SUCCESS.getType());
        } else if (TradeStatusEnums.TRADE_CLOSED.getCode().equals(payAsyncVo.getTrade_status())) {
            updateWrapper = new UpdateWrapper<OrderInfo>().eq("order_no", payAsyncVo.getOut_trade_no()).eq("order_status", OrderStatus.NOTPAY.getType()).set("out_trade_no", payAsyncVo.getTrade_no())
                    .set("buyer_id", payAsyncVo.getBuyer_id()).set("invoice_amount", payAsyncVo.getInvoice_amount()).set("receipt_amount", payAsyncVo.getReceipt_amount()).set("order_status", OrderStatus.CLOSED.getType());
        } else if (TradeStatusEnums.WAIT_BUYER_PAY.getCode().equals(payAsyncVo.getTrade_status())) {
            updateWrapper = new UpdateWrapper<OrderInfo>().eq("order_no", payAsyncVo.getOut_trade_no()).eq("order_status", OrderStatus.NOTPAY.getType()).set("out_trade_no", payAsyncVo.getTrade_no())
                    .set("buyer_id", payAsyncVo.getBuyer_id()).set("invoice_amount", payAsyncVo.getInvoice_amount()).set("receipt_amount", payAsyncVo.getReceipt_amount()).set("order_status", OrderStatus.WAITPAY.getType());
        }
        this.update(updateWrapper);
    }


}
